iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Modern Web

前進React 生態系 : 技術應用與概念解析系列 第 28

Day 28 - React Server Components 原理解析

  • 分享至 

  • xImage
  •  

Server Components 的主要特點是將資料處理和元件渲染都在 Server 端完成,然後再將結果傳送至 Client 端。接下來的內容將著重在如何將在 Server 端生成的 React Component 傳送至 Client 端。這些 Server Components 會被轉換為一種特殊格式,稱為 RSC Payload。

RSC Payload 是什麼?

RSC Payload 會是在 Server 端渲染的 React Server Components 樹狀結構,RSC Payload 包含以下內容:

  • Server 端渲染的 Server Components 結果
  • 標記出 Client 端需要渲染的 Client Components,以及對應的 JavaScript 模組引用
  • Server Components 傳遞給 Client Components 的 props

結構會類似這樣:

0:"$L1"
1:["$","h1",null,{"children":"Hello World!"}]
//...

當 RSC Payload 傳送到 Client 端後,會經過轉換變成 React Elements,最後呈現在瀏覽器中。

為什麼不使用 HTML ?

主要是因為 Server Component 中會包含到 Client Component,而 Client Component 會包含狀態和事件處理函數,這些內容無法被簡單序列化。RSC Payload 能夠更方便地處理這些狀態,並確保在重新渲染的過程中,這些狀態相關的內容可以被正確保留。

在 Client 端怎麼處理 RSC Payload ?

RSC Payload 會透過 createFromFetch 轉換成 React Element。以下是簡單的範例說明:

import { use } from "react";
import { createFromFetch } from "react-server-dom-esm/client";

const initialContentPromise = createFromFetch(fetch("/rsc?...")); // RSC Payload
function Root() {
  const content = use(initialContentPromise);
  return content;
}

createFromFetch 將 RSC Payload 轉換成 React Element,並且透過 use 取得 Promise 的內容,也就是轉換過後回傳的 React Element。

"use client" 做了什麼?

"use client" 可以當成 Client 和 Server 的邊界。或者是根據 Dan Abramov 的說法,可以想成是前往 Client 世界的門。

當偵測到 "use client" 時,會將其轉換為使用模組的引用。在 RSC Payload 中,Client Component 會以模組引用的形式存在,會類似下面這樣:

b:I["/some-component.js","SomeComponent"]

前面會是模組的路徑位置,後面則是需要導出的內容。

流程說明

雖然 Server Components 也可以在 CSR 使用,但大部分框架都是支援 SSR 的。以下是使用 SSR 和 Server Components 的運作流程:

Server 端

  1. 將 Server Components 渲染成 RSC Payload
  2. 透過 RSC Payload 和 Client Component 的 JavaScript 模組來生成呈現的 HTML

Client 端

  1. 只有當初始頁面載入時,Server 端會回傳生成的 HTML,這部分也就是所謂的 SSR。
  2. 接收 RSC Payload:客戶端接收來自伺服器的 RSC Payload。
  3. 使用 createFromFetch 將 RSC Payload 轉換成 React Element。
  4. React 根據轉換後的 React Elements 進行渲染,並更新 DOM。
  5. 透過 Hydration 轉換為可以互動的 React 元件。

後續重新渲染:如果因為用戶操作或資料變更需要重新渲染某些 Component,Server 端會生成新的 RSC Payload 傳到 Client 端,Client 端再更新 DOM。

這篇文章沒有討論到 Server Functions、Async Component 和 router 等相關內容,這些內容的整合起來會很複雜,所以都會是使用框架來實作,像是 Next.js 或是 Remix 等。

參考資料:
https://www.plasmic.app/blog/how-react-server-components-work
https://www.youtube.com/watch?v=pOo7x8OiAec
https://www.youtube.com/watch?v=ozI4V_29fj4
https://nextjs.org/docs/app/building-your-application/rendering/server-components#how-are-server-components-rendered
https://www.smashingmagazine.com/2024/05/forensics-react-server-components/


上一篇
Day 27 - Streaming SSR 原理解析
下一篇
Day 29 - React Hooks 原理解析
系列文
前進React 生態系 : 技術應用與概念解析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言